package telltale;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

/*
 * Creates a new log file every day, aka "rollover".
 */

public class 
	RollingFileAdapter
extends 
	FileAdapter 
{
	public final static String DEFAULT_FILENAME_PATTERN = "yyyy-MM-dd";

	private String _pattern = DEFAULT_FILENAME_PATTERN;
	
	public void setPattern( String pattern )
	{
		if( pattern == null )
		{
			throw new NullPointerException( "pattern" );
		}
		// TODO: validate pattern with trial run
		_pattern = pattern;
		_formatter = null;
	}
	
	public String getPattern()
	{
		return _pattern;
	}

	// specified in bytes here, but properties file and setter method
	// both specify it in megabytes
	// 0 means there is no maximum filesize
	private long _maxFilesize = 0;
	
	/**
	 * Specify in MB. 0 signifies no maximum filesize.
	 */
	public void setMaxFilesize( long maxFilesize )
	{
		_maxFilesize = 1048576 * maxFilesize;
	}

	// Not threadsafe, so we keep our own instance
	private SimpleDateFormat _formatter = null;
	
	private SimpleDateFormat getFormatter() 
	{
		if( _formatter == null )
		{
			_formatter = new SimpleDateFormat( _pattern );
		}
		return _formatter;
	}
	
	private File _file = null;

	public FileOutputStream getOutputStream() 
		throws IOException
	{
		if( _file == null )
		{
			String filename = getFileName() + "." + getExtension();
			_file = new File( getDirectory(), filename );
		}
		
		long modified = _file.lastModified();
		long midnight = midnight();

		boolean a = modified != 0L && modified < midnight;
		boolean b = _file.length() > _maxFilesize;
		if( a || b )
		{
			if( _out != null )
			{
				_out.close();
				_out = null;
			}
			
			Date temp = new Date( yesterday() );
			String date = getFormatter().format( temp );
			String ugh = "";
			int nth = 0;
			File rename = null;
			while( true )
			{
				String retired = getFileName() + "." + date + "." + ugh + getExtension();
				rename = new File( getDirectory(), retired );
				if( !rename.exists() ) break;
				nth++;
				ugh = Integer.toString( nth ) + ".";
			}
			_file.renameTo( rename );
		}
		
		if( _out == null )
		{
			_out = new FileOutputStream( _file, true );
		}
		return _out;
	}

	public static long MILLIS_PER_DAY = 1000 * 60 * 60 * 24; 
	
	// Number of milliseconds in a day
	public static long midnight() 
	{
		long now = System.currentTimeMillis();
		long offset = TimeZone.getDefault().getOffset( now );
	    long msPortion = ( now + offset ) % MILLIS_PER_DAY;
	    
	    return now - msPortion;
	}

	public static long yesterday()
	{
		return midnight() - MILLIS_PER_DAY;
	}
}
